package com.auto.api.core.type;

import com.auto.api.core.type.classtomap.ClassToColumnTypeMapHandler;
import com.auto.api.core.type.classtomap.ClassToParamColumnMapHandler;
import com.auto.api.core.type.classtomap.ClassToResultApiMapHandler;
import com.auto.api.core.type.classtomap.ClassToResultColumnMapHandler;
import com.auto.api.core.type.classtotorna.ClassToTornaResultApiHandler;
import com.auto.api.core.type.defaultvalue.BigDecimalTypeHandler;
import com.auto.api.core.type.defaultvalue.BooleanTypeHandler;
import com.auto.api.core.type.defaultvalue.ByteTypeHandler;
import com.auto.api.core.type.defaultvalue.DateTypeHandler;
import com.auto.api.core.type.defaultvalue.DoubleTypeHandler;
import com.auto.api.core.type.defaultvalue.EnumTypeHandler;
import com.auto.api.core.type.defaultvalue.FloatTypeHandler;
import com.auto.api.core.type.defaultvalue.IntegerTypeHandler;
import com.auto.api.core.type.defaultvalue.ListTypeHandler;
import com.auto.api.core.type.defaultvalue.LocalDateTimeTypeHandler;
import com.auto.api.core.type.defaultvalue.LocalDateTypeHandler;
import com.auto.api.core.type.defaultvalue.LocalTimeTypeHandler;
import com.auto.api.core.type.defaultvalue.LongTypeHandler;
import com.auto.api.core.type.defaultvalue.MapTypeHandler;
import com.auto.api.core.type.defaultvalue.MultipartFileTypeHandler;
import com.auto.api.core.type.defaultvalue.ObjectTypeHandler;
import com.auto.api.core.type.defaultvalue.ShortTypeHandler;
import com.auto.api.core.type.defaultvalue.StringTypeHandler;
import com.auto.api.core.type.defaultvalue.ValueTypeHandler;
import com.auto.api.core.type.marge.BeanMargeHandlerImpl;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.apache.commons.lang3.StringUtils;

/**
 * @program:
 * @description: 类型工具工厂
 * @author: liangshf
 * @create: 2020-09-24
 */
public class TypeFactory {

    private final static Map<String, ValueTypeHandler> typeHandlerMap = new HashMap<>();
    private final static Map<String, ParseBeanHandler> parseBeanMap = new HashMap<>();

    public static final String CLASS_TO_RESULT_COLUMN_MAP = "ClassToResultColumnMap";
    /**
     * Class类型转换解析YaPi结果集返回json
     */
    public static final String CLASS_TO_RESULT_API_MAP = "ClassToResultApiMap";
    public static final String CLASS_TO_COLUMN_TYPE_MAP = "ClassToColumnTypeMap";
    public static final String CLASS_TO_PARAM_COLUMN_MAP = "ClassToParamColumnMap";
    public static final String BEAN_MARGE = "BeanMarge";
    public static final String CLASS_TO_TORNA_RESULT_API_MAP = "ClassToTornaResultApiMap";

    public static final String STRING_BOX = "String";
    public static final String INTEGER_BOX = "Integer";
    public static final String BIG_DECIMAL_BOX = "BigDecimal";
    public static final String BOOLEAN_BOX = "Boolean";
    public static final String DOUBLE_BOX = "Double";
    public static final String FLOAT_BOX = "Float";
    public static final String LIST_BOX = "List";
    public static final String LONG_BOX = "Long";
    public static final String DATE_BOX = "Date";
    public static final String LOCAL_DATE_TIME_BOX = "LocalDateTime";
    public static final String LOCAL_DATE_BOX = "LocalDate";
    public static final String LOCALTIME_BOX = "LocalTime";
    public static final String SHORT_BOX = "LocalTime";
    public static final String MAP_BOX = "Map";
    public static final String ENUM_BOX = "Enum";
    public static final String BYTE_BOX = "Byte";
    public static final String MULTI_PART_FILE_BOX = "MultipartFile";
    public static final String OBJECT_BOX = "Object";

    private static final String TEXT_DOUBLE = "double";
    private static final String TEXT_FLOAT = "float";
    private static final String TEXT_SHORT = "short";
    private static final String TEXT_BOOLEAN = "boolean";
    private static final String TEXT_LONG = "long";
    private static final String TEXT_INT = "int";
    private static final String BYTE = "byte";


    /**
     * 集合类型
     */
    public static final List<String> collectionType = Arrays
        .asList("int[]", "long[]", "Set", "String[]", "List", "Collection");

    static {
        typeHandlerMap.put(STRING_BOX, new StringTypeHandler());
        typeHandlerMap.put(INTEGER_BOX, new IntegerTypeHandler());
        typeHandlerMap.put(BIG_DECIMAL_BOX, new BigDecimalTypeHandler());
        typeHandlerMap.put(BOOLEAN_BOX, new BooleanTypeHandler());
        typeHandlerMap.put(DOUBLE_BOX, new DoubleTypeHandler());
        typeHandlerMap.put(FLOAT_BOX, new FloatTypeHandler());
        typeHandlerMap.put(LIST_BOX, new ListTypeHandler());
        typeHandlerMap.put(LONG_BOX, new LongTypeHandler());
        typeHandlerMap.put(DATE_BOX, new DateTypeHandler());
        typeHandlerMap.put(LOCAL_DATE_TIME_BOX, new LocalDateTimeTypeHandler());
        typeHandlerMap.put(LOCAL_DATE_BOX, new LocalDateTypeHandler());
        typeHandlerMap.put(LOCALTIME_BOX, new LocalTimeTypeHandler());
        typeHandlerMap.put(SHORT_BOX, new ShortTypeHandler());
        typeHandlerMap.put(MAP_BOX, new MapTypeHandler());
        typeHandlerMap.put(ENUM_BOX, new EnumTypeHandler());
        typeHandlerMap.put(BYTE_BOX, new ByteTypeHandler());
        typeHandlerMap.put(MULTI_PART_FILE_BOX, new MultipartFileTypeHandler());
        typeHandlerMap.put(OBJECT_BOX, new ObjectTypeHandler());

        parseBeanMap.put(CLASS_TO_RESULT_COLUMN_MAP, new ClassToResultColumnMapHandler());
        parseBeanMap.put(CLASS_TO_RESULT_API_MAP, new ClassToResultApiMapHandler());
        parseBeanMap.put(CLASS_TO_COLUMN_TYPE_MAP, new ClassToColumnTypeMapHandler());
        parseBeanMap.put(CLASS_TO_PARAM_COLUMN_MAP, new ClassToParamColumnMapHandler());
        parseBeanMap.put(BEAN_MARGE, new BeanMargeHandlerImpl());
        parseBeanMap.put(CLASS_TO_TORNA_RESULT_API_MAP, new ClassToTornaResultApiHandler());
    }

    public static ValueTypeHandler getTypeHandler(String simpleType) {
        if (StringUtils.isNotBlank(simpleType)) {
            return typeHandlerMap.get(getBoxType(simpleType));
        }
        return null;
    }

    public static boolean isSimpleTypeHandler(String simpleType) {
        if (StringUtils.isNotBlank(simpleType)) {
            return typeHandlerMap.containsKey(getBoxType(simpleType));
        }
        return false;
    }

    public static ParseBeanHandler getParseBeanHandler(String columnResultType) {
        if (StringUtils.isEmpty(columnResultType)) {
            throw new RuntimeException("columnResultType is null");
        }
        ParseBeanHandler beanHandler = parseBeanMap.get(columnResultType);
        if (Objects.isNull(beanHandler)) {
            throw new RuntimeException("get ClassToMapTypeHandler is null");
        }
        return beanHandler;
    }

    public static String getBoxType(String simpleType) {
        if (TEXT_INT.equals(simpleType)) {
            return STRING_BOX;
        } else if (TEXT_BOOLEAN.equals(simpleType)) {
            return BOOLEAN_BOX;
        } else if (TEXT_LONG.equals(simpleType)) {
            return LONG_BOX;
        } else if (TEXT_FLOAT.equals(simpleType)) {
            return FLOAT_BOX;
        } else if (TEXT_DOUBLE.equals(simpleType)) {
            return DOUBLE_BOX;
        } else if (TEXT_SHORT.equals(simpleType)) {
            return SHORT_BOX;
        } else if (BYTE.equals(simpleType)) {
            return BYTE_BOX;
        } else if (collectionType.contains(simpleType)) {
            return LIST_BOX;
        }
        return simpleType;
    }

}